home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-19 | 5.2 KB | 172 lines | [TEXT/CWIE] |
- /*
- Problem 05 - Database
-
- type
- StringsHandle = Handle; // Sequence of Pascal Strings packed together
- DatabaseHandle = Handle; // Must be a real handle
-
- procedure DatabaseInit( var database: Handle; field_count: UInt32 );
- procedure DatabaseAddEntry( database: Handle; entry: StringsHandle );
- procedure DatabaseFindEntry( database: Handle; field: UInt32; const match:
- Str255; var entry: StringsHandle );
- procedure DatabaseDeleteEntry( database: Handle; field: UInt32; const match:
- Str255 );
- function DatabaseCount( database: Handle ): UInt32;
- procedure DatabaseGetIndEntry( database: Handle; index: UInt32; var entry:
- StringsHandle );
-
- Your task is to write a set of routines to maintain a database.
-
- DatabaseInit creates a new, empty database ready to accept records with
- field_count string fields. The database is stored in the database Handle.
-
- DatabaseAddEntry adds an entry (which is a Handle to field_count pascal strings
- packed together conceptually numbered 1 to field_count)
-
- DatabaseFindEntry finds an entry whose field (between 1 and field_count) string
- is exactly equal to match. The entry is returned in a newly created handle
- (which will be disposed of using DisposeHandle). Return nil if no match is
- found. If more than one entry matches, you must return the earliest added
- entry.
-
- DatabaseDeleteEntry finds the entry that DatabaseFindEntry would find, and if
- found removes it from the database.
-
- DatabaseCount returns the number of entries in the database.
-
- DatabaseGetIndEntry returns the entries in the Database in the order they were
- entered, 1 for the earliest entered, DatabaseCount the last entered.
-
- All the database information must be stored in the real Mac memory manager
- handle - it will be disposed with DisposeHandle and that must release all
- memory, so do not store any extra information outside the handle. Also, you
- must be able to deal with having multiple databases instantiated
- simultaneously.
-
- You will not be given invalid parameters so you don't need to handle error
- checking, and there will be plenty of memory.
-
- All strings are case sensitive (ie, treated as eight bit binary data).
- */
-
- #include "Solution.h"
-
- #include <string.h>
-
- UInt32 gFieldCount;
- // Fill in your solution and then submit this folder
-
- // Team Name: Three And One
-
- pascal void DatabaseInit( DatabaseHandle *database, UInt32 field_count )
- {
- gFieldCount = field_count;
- *database = NewHandle(0);
- }
-
- pascal void DatabaseAddEntry( DatabaseHandle database, StringsHandle entry )
- {
- HandAndHand(entry, database);
- }
-
- static unsigned char *
- FindNextEntry(unsigned char * entry)
- {
- for (UInt32 currentField = 1; currentField <= gFieldCount; currentField++)
- entry += entry[0] + 1;
-
- return entry;
- }
-
- static unsigned char *
- FindField(unsigned char * entry, UInt32 field)
- {
- for (UInt32 currentField = 1; currentField < field; currentField++)
- entry += entry[0] + 1;
-
- return entry;
- }
-
- UInt32
- EntrySize(unsigned char *entry)
- {
- UInt32 size = 0;
- unsigned char *field = entry;
- for (short i = 1; i <= gFieldCount; i++)
- {
- size += field[0] + 1;
- field += field[0] + 1;
- }
- return size;
- }
-
- StringsHandle
- NewEntryHandle(unsigned char *entry)
- {
- UInt32 entrySize = EntrySize(entry);
- Handle entryHandle = NewHandle(entrySize);
- memcpy(*entryHandle, entry, entrySize);
- return entryHandle;
- }
-
- pascal void DatabaseFindEntry( DatabaseHandle database, UInt32 field, ConstStr255Param match, StringsHandle *entry )
- {
- UInt32 matchLength = match[0];
- unsigned char *currentEntry = (unsigned char*)*database;
-
- while (currentEntry < GetHandleSize(database) + (unsigned char*)*database)
- {
- unsigned char *currentField = FindField(currentEntry, field);
- if (matchLength == currentField[0] && !strncmp((const char *)currentField, (const char *)match, matchLength + 1))
- {
- *entry = NewEntryHandle(currentEntry);
- return;
- }
-
- currentEntry = FindNextEntry(currentEntry);
- }
-
- *entry = NULL;
- }
-
- pascal void DatabaseDeleteEntry( DatabaseHandle database, UInt32 field, ConstStr255Param match )
- {
- UInt32 matchLength = match[0];
- unsigned char * currentEntry = (unsigned char*)*database;
- UInt32 databaseSize = GetHandleSize(database);
-
- while (currentEntry < databaseSize + (unsigned char*)*database)
- {
- unsigned char *currentField = FindField(currentEntry, field);
- if (matchLength == currentField[0] && !strncmp((const char *)currentField, (const char *)match, matchLength + 1))
- {
- UInt32 entrySize = EntrySize(currentEntry);
- memmove(currentEntry, currentEntry + entrySize, (unsigned char*)*database + databaseSize - currentEntry - entrySize);
- SetHandleSize(database, databaseSize - entrySize);
- return;
- }
-
- currentEntry = FindNextEntry(currentEntry);
- }
- }
-
- pascal UInt32 DatabaseCount( DatabaseHandle database )
- {
- unsigned char * currentEntry = (unsigned char*)*database;
- short count;
- for (count = 0; currentEntry < GetHandleSize(database) + (unsigned char*)*database; count++)
- currentEntry = FindNextEntry(currentEntry);
- return count;
- }
-
- pascal void DatabaseGetIndEntry( DatabaseHandle database, UInt32 index, StringsHandle *entry )
- {
- unsigned char *currentEntry = (unsigned char*)*database;
-
- for (short i = 1; i < index; i++)
- currentEntry = FindNextEntry(currentEntry);
-
- *entry = NewEntryHandle(currentEntry);
- }
-
-